package com.gopay.cron.service.fund.impl;

import com.gopay.common.constants.fund.FundAcctStrEnum;
import com.gopay.common.constants.fund.FundConstants;
import com.gopay.common.constants.fund.FundSettleStatusEnum;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.service.fund.FundOrderService;
import com.gopay.common.domain.acps.model.AcctMastBean;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.transfer.Tran02020Detail;
import com.gopay.common.domain.cps.transfer.Tran02020VO;
import com.gopay.common.domain.cps.vo.CPSResponse;
import com.gopay.common.domain.fund.FundGopayCpsGenOrder;
import com.gopay.common.exception.FundException;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.FastJsonUtil;
import com.gopay.cron.service.fund.FundFastPayService;
import com.gopay.cron.web.util.CallCPSUtil;
import com.gopay.remote.fundcps.service.FundCpsGenOrderService;
import com.gopay.scheduler.service.fund.FundAcctMastService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service(value = "fundFastPayService")
public class FundFastPayServiceImpl implements FundFastPayService {
    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(FundFastPayServiceImpl.class);

    @Resource(name = "fundCpsGenOrderService")
    private FundCpsGenOrderService fundCpsGenOrderService;

    @Autowired
    private FundOrderService fundOrderService;

    @Autowired
    private FundAcctMastService fundAcctMastService;

    @Override
    public void fastPay(Date startTime, Date endTime) {
        try {
            logger.info("【活期宝快速赎回付款处理】活期宝生成基金转国付宝订单基金公司编码：{}，打包开始时间：{}，打包截止时间：{}", new Object[]{FundConstants.FUND_RTFUND, startTime, endTime});
            String gopayOrderId02018 = fundCpsGenOrderService.gen02018OrderToFastPay(FundConstants.FUND_RTFUND, startTime, endTime);
            if (StringUtils.isNotBlank(gopayOrderId02018)) {
                logger.info("【活期宝快速赎回付款处理】生成基金转国付宝订单成功，国付宝订单号：{}。开始执行打款操作", gopayOrderId02018);
                List<CpsGenMainOrder> mainOrdersList02020 = fundOrderService.getCpsGenMainOrder4Settle(gopayOrderId02018, IntTxnCd._02020.value);
                logger.info("【活期宝快速赎回付款处理】获取的需要处理的02020订单数量：{}", mainOrdersList02020.size());
                if (mainOrdersList02020.size() > 0) {
                    try {
                        //更改02018订单状态为付款进行中
                        fundOrderService.updateFundAndMainOrderByGopayOrderId(gopayOrderId02018, FundSettleStatusEnum.PAY_LOADING.getValue(), TxnStaCode.TXN_STA_CD_30000.value);

                        Tran02020VO tran02020VO = init02020TranVo(mainOrdersList02020, gopayOrderId02018, null);
                        logger.info("【活期宝快速赎回付款处理】CPS活期宝付款业务开始，发送对象明细：{}", FastJsonUtil.toJSONString(tran02020VO));
                        CPSResponse cpsResponse = CallCPSUtil.callByVOTicket(tran02020VO);
                        logger.info("【活期宝快速赎回付款处理】CPS活期宝付款业务结束，反馈结果：{}", FastJsonUtil.toJSONString(cpsResponse));

                        String errMsg;
                        FundGopayCpsGenOrder fundOrder02018 = fundOrderService.getFundOrderByGopayOrderId(gopayOrderId02018);
                        if (cpsResponse != null && ProcCodeConstants.PROC_CODE_000S1000.equals(cpsResponse.getRespCode())) {
                            logger.info("【活期宝快速赎回付款处理】CPS活期宝付款业务成功，更新02018反馈");
                            errMsg = "成功";
                        } else {
                            logger.info("【活期宝快速赎回付款处理】CPS活期宝付款业务失败，更新02018反馈");
                            fundOrder02018.setOrderType(FundSettleStatusEnum.NEED_SETTLE.getValue());
                            if(null == cpsResponse){
                                errMsg = "cps无响应";
                            } else {
                                errMsg = cpsResponse.getRespMessage() == null ? cpsResponse.getRespCode() : cpsResponse.getRespMessage();
                                if (errMsg.length() > 128) {
                                    errMsg = errMsg.substring(0, 128);
                                }
                            }
                        }
                        fundOrder02018.setLastErrorMsg(errMsg);
                        fundOrderService.updateFundOrder(fundOrder02018);
                    } catch (GopayException e) {
                        logger.error("【活期宝快速赎回付款处理】CPS活期宝付款业务发生异常[tran02020VO]", e);
                        //恢复02018 基金订单状态为20 待结算
                        fundOrderService.updateFundCpsOrderTypeByGopayOrderId(gopayOrderId02018, FundSettleStatusEnum.NEED_SETTLE.getValue());

                    }
                }
            } else {
                logger.error("【活期宝快速赎回付款处理】生成基金转国付宝订单失败，请检查原因。");
            }
        } catch (FundException e) {
            logger.error("【活期宝快速赎回付款处理】发生阻断，原因：{}", e.toString());
        } catch (Exception e) {
            logger.error("【活期宝快速赎回付款处理】发生未知异常！", e);
        }
    }

    /**
     * 商财通，退款传输订单初始化
     *
     * @param mainOrders02020   : 活期宝订单明细
     * @param gopayOrderId02018 : 02018订单号
     * @return com.gopay.common.domain.cps.transfer.Tran02014VO
     * @author yhwpeng@126.com
     * @date 2017-12-28 16:15:36
     * @params
     */
    public Tran02020VO init02020TranVo(List<CpsGenMainOrder> mainOrders02020, String gopayOrderId02018, String userId) {
        List<Tran02020Detail> voList = new ArrayList<>();
        for (CpsGenMainOrder order : mainOrders02020) {
            Tran02020Detail vo = new Tran02020Detail();
            vo.setGopayOrderId(order.getGopayOrderId());
            vo.setMerTxnAmt(order.getTotalOrderAmt());
            vo.setUserId(userId);
            voList.add(vo);
        }
        Tran02020VO tran02020VO = new Tran02020VO();
        tran02020VO.setMainGopayOrderId(gopayOrderId02018);
        tran02020VO.setVoList(voList);
        FundGopayCpsGenOrder fundGopayOrder02018 = fundOrderService.getFundOrderByGopayOrderId(gopayOrderId02018);
        AcctMastBean account = fundAcctMastService.getAccount(fundGopayOrder02018.getMerchantId(), FundAcctStrEnum.FDSFT.getValue());
        tran02020VO.setAcctIdSFT(account.getAcctId());
        return tran02020VO;
    }
}
